﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Outpatient.Infrastructure
{
    public class BasreRepository<T>:IBaseRepository<T> where T : class
    {
        private readonly ILogger<BasreRepository<T>> logger;
        private readonly EFDbContext ctx;

        public BasreRepository(ILogger<BasreRepository<T>> logger,EFDbContext ctx)
        {
            this.logger = logger;
            this.ctx = ctx;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<int> AddAsyn(T t)
        {
            try
            {
                await ctx.Set<T>().AddAsync(t);
                return await ctx.SaveChangesAsync();
            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public Task<int> Batchadd(List<T> t)
        {
            try
            {
                ctx.Set<T>().AddRange(t);
                return ctx.SaveChangesAsync();
            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public Task<int> BatchUpdate(List<T> t)
        {
            try
            {
                ctx.Set<T>().UpdateRange(t);
                return ctx.SaveChangesAsync();

            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public IQueryable<T> Getlist()
        {
            try
            {
                return ctx.Set<T>().AsQueryable();
            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        
        /// <summary>
        /// 安全查询，处理可能的NULL值
        /// </summary>
        /// <returns>安全的查询对象</returns>
        public IQueryable<T> GetSafeList()
        {
            try
            {
                // 配置查询以防止NULL值转换异常
                return ctx.Set<T>().AsNoTracking().AsQueryable();
            }
            catch (Exception ex)
            {
                logger.LogError($"安全查询出错: {ex.Message}");
                throw;
            }
        }
        
        /// <summary>
        /// 根据条件查找信息
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        public async Task<T> GetValue(Expression<Func<T, bool>> exp)
        {
            try
            {
                return await ctx.Set<T>().Where(exp).FirstOrDefaultAsync();
            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public Task<int> Update(T t)
        {
            try
            {
                ctx.Set<T>().Update(t);
                return ctx.SaveChangesAsync();
            }
            catch (Exception ex)
            {

                logger.LogError("=>" + ex.Message);
                throw ex;
            }
        }
        
        /// <summary>
        /// 异步批量添加
        /// </summary>
        /// <param name="entities">实体列表</param>
        /// <returns>任务</returns>
        public async Task AddRangeAsync(List<T> entities)
        {
            try
            {
                await ctx.Set<T>().AddRangeAsync(entities);
            }
            catch (Exception ex)
            {
                logger.LogError($"批量添加出错: {ex.Message}");
                throw;
            }
        }
        
        /// <summary>
        /// 保存更改到数据库
        /// </summary>
        /// <returns>受影响的行数</returns>
        public async Task<int> SaveAsync()
        {
            try
            {
                return await ctx.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                logger.LogError($"保存数据出错: {ex.Message}");
                throw;
            }
        }
        
        /// <summary>
        /// 获取数据库上下文
        /// </summary>
        /// <returns>数据库上下文</returns>
        public DbContext GetDbContext()
        {
            return ctx;
        }
        
        /// <summary>
        /// 安全执行SQL查询，避免NULL转换异常
        /// </summary>
        /// <typeparam name="TResult">返回类型</typeparam>
        /// <param name="sql">SQL查询语句</param>
        /// <param name="parameters">查询参数</param>
        /// <returns>查询结果</returns>
        public async Task<List<TResult>> ExecuteSafeSqlQuery<TResult>(string sql, params object[] parameters) where TResult : class, new()
        {
            try
            {
                // 使用原始SQL查询
                var connection = ctx.Database.GetDbConnection();
                var command = connection.CreateCommand();
                command.CommandText = sql;
                
                // 确保连接打开
                if (connection.State != System.Data.ConnectionState.Open)
                {
                    await connection.OpenAsync();
                }
                
                // 执行查询
                var results = new List<TResult>();
                using (var reader = await command.ExecuteReaderAsync())
                {
                    var propertyCache = typeof(TResult).GetProperties().ToDictionary(p => p.Name.ToLower(), p => p);
                    
                    while (await reader.ReadAsync())
                    {
                        var result = new TResult();
                        
                        // 遍历所有列
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            string columnName = reader.GetName(i).ToLower();
                            
                            // 检查是否存在匹配的属性
                            if (propertyCache.TryGetValue(columnName, out var property))
                            {
                                // 安全处理NULL值
                                if (!reader.IsDBNull(i))
                                {
                                    var value = reader.GetValue(i);
                                    
                                    // 转换值到属性类型
                                    if (property.PropertyType == typeof(string))
                                    {
                                        property.SetValue(result, value.ToString());
                                    }
                                    else
                                    {
                                        try
                                        {
                                            // 尝试转换为目标类型
                                            property.SetValue(result, Convert.ChangeType(value, property.PropertyType));
                                        }
                                        catch
                                        {
                                            // 如果转换失败，设置为默认值
                                            property.SetValue(result, null);
                                        }
                                    }
                                }
                                else
                                {
                                    // 设置为NULL或默认值
                                    property.SetValue(result, null);
                                }
                            }
                        }
                        
                        results.Add(result);
                    }
                }
                
                return results;
            }
            catch (Exception ex)
            {
                logger.LogError($"执行SQL查询时发生错误: {ex.Message}");
                throw;
            }
        }
    }
}
